package com.smedi.ismedi.authoritymanagement.core.application.service.impl;

import com.smedi.ismedi.authoritymanagement.core.application.command.*;
import com.smedi.ismedi.authoritymanagement.core.application.service.AuthorityInfrastructureApplicationService;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.*;
import com.smedi.ismedi.authoritymanagement.core.domain.service.FrameStructureDomainService;
import com.smedi.ismedi.authoritymanagement.core.domain.service.TermRelationshipGroupDomainService;
import com.smedi.ismedi.authoritymanagement.core.domain.service.TermDomainService;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: xulinjun
 * @Date: 2021-7-15 20:44
 */
@Slf4j
@Service
@AllArgsConstructor
public class AuthorityInfrastructureApplicationServiceImpl implements AuthorityInfrastructureApplicationService {
    private final DozerUtil dozerUtil;

    private final TermDomainService termDomainService;

    private final TermRelationshipGroupDomainService termRelationshipGroupDomainService;

    private final FrameStructureDomainService frameStructureDomainService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<TermPage> batchSaveTermPage(List<TermPageCommand> termCommands) {
        return termCommands.stream().map(termCommand ->
                termDomainService.saveTerm(dozerUtil.convertor(termCommand, TermPage.class))
        ).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<TermMenu> batchSaveTermMenu(List<TermMenuCommand> termCommands) {
        return termCommands.stream().map(termCommand ->
                termDomainService.saveTerm(dozerUtil.convertor(termCommand, TermMenu.class))
        ).collect(Collectors.toList());
    }

    @Override
    public List<TermRouter> batchSaveTermRouter(List<TermRouterCommand> termCommands) {
        return termCommands.stream().map(termCommand ->
                termDomainService.saveTerm(dozerUtil.convertor(termCommand, TermRouter.class))
        ).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<TermRelationshipGroupType> batchSaveRolePermissionType(List<TermRelationshipGroupCommand> termRelationshipGroupCommands) {
        return termRelationshipGroupCommands.stream().map(termRelationshipGroupCommand -> termRelationshipGroupDomainService.saveRolePermissionType(
                dozerUtil.convertor(termRelationshipGroupCommand, TermRelationshipGroupType.class)
        )).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FrameStructure saveFrameStructure(FrameStructureCommand frameStructureCommand) {
        FrameStructure frameStructure = dozerUtil.convertor(frameStructureCommand, FrameStructure.class);

        // 获取所有的授权类型
        List<TermRelationshipGroupType> termRelationshipGroupTypes = termRelationshipGroupDomainService.getAllRolePermissionTypes();
        // 校验传入的菜单结构
        frameStructureDomainService.validateMenuStructure(frameStructure, termRelationshipGroupTypes, true);
        // 如果通过校验后，清除传入的节点下的所有数据
        if (frameStructure.getStructureId() != null) {
            frameStructureDomainService.dropChildrenByStructureId(frameStructure.getStructureId(), true);
        }

        // 以当前节点为起点开始保存
        FrameStructure domain = frameStructureDomainService.saveAllFrameStructure(frameStructure);
        return domain;
    }

}
